package com.chinaoly.baotou.web.controller;

import com.alibaba.fastjson.JSON;
import com.chinaoly.baotou.common.page.BasePageForm;
import com.chinaoly.baotou.common.page.P;
import com.chinaoly.baotou.common.utils.EsUtil;
import com.chinaoly.baotou.dao.mapper.OfficeMapper;
import com.chinaoly.baotou.dao.mapper.UserMapper;
import com.chinaoly.baotou.model.sendMessage.User;
import com.chinaoly.frm.core.entity.Result;
import com.chinaoly.frm.core.entity.ResultGenerator;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * es官方文档：https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.10/java-rest-high-supported-apis.html
 * @author Gordon
 * @date 2022/7/15
 **/
@Api(tags = "es基本用法测试")
@RequestMapping("/ceshi")
@RestController
@Slf4j
public class TestController {

    private static String indexName = "user_index";

    @Resource
    private EsUtil esUtil;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OfficeMapper officeMapper;


    @PostMapping("/mysql")
    @ApiOperation(value = "mysql数据查询(摘要)", notes = "notes-上传附件(注释/接口描述)")
    public Result uploadNotRelation() {
        return ResultGenerator.genSuccessResult(userMapper.selectByPrimaryKey(31));
    }

    @PostMapping("/oracle")
    @ApiOperation(value = "接口摘要", notes = "接口描述")
    public Result uploadFile() {
        return ResultGenerator.genSuccessResult(officeMapper.selectByPrimaryKey("152224480000"));
    }

    @ApiOperation(value = "创建索引")
    @GetMapping("/createIndex")
    public Boolean create(@RequestParam("indexName") String indexName) {
        return esUtil.createIndex(indexName);
    }

    @ApiOperation(value = "查询索引 * 查询全部")
    @GetMapping("searchIndex")
    public List<String> searchIndex(@RequestParam("indexName") String indexName) {
        return esUtil.searchIndex(indexName);
    }

    @ApiOperation(value = "删除索引")
    @GetMapping("deleteIndex")

    public Boolean deleteIndex(@RequestParam("indexName") String indexName) {
        return esUtil.deleteIndex(indexName);
    }


    @ApiOperation(value = "插入文档")
    @GetMapping("insert")
    public String insert(@RequestParam("id") String id) {
        User user = new User().setUserName("张三").setAge(22).setCreateTime(System.currentTimeMillis());
        return esUtil.insert(indexName, id, JSON.toJSONString(user));
    }

    @ApiOperation(value = "批量插入")
    @GetMapping("insertBatch")
    public BulkResponse insertBatch() {
        Map<String, String> build = new ImmutableMap.Builder<String, String>()
                .put("1", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis()).setUserName("张三").setAge(22)))
                .put("2", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 10000).setUserName("王五").setAge(23)))
                .put("3", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 20000).setUserName("张三").setAge(25)))
                .put("4", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 30000).setUserName("王五").setAge(26)))
                .put("5", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 40000).setUserName("张三").setAge(28)))
                .put("6", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 50000).setUserName("王五").setAge(27)))
                .put("7", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 60000).setUserName("张三").setAge(24)))
                .put("8", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 70000).setUserName("王五").setAge(22)))
                .put("9", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 80000).setUserName("张三").setAge(23)))
                .put("10", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 90000).setUserName("王五").setAge(23)))
                .build();
        return esUtil.insertBatch(indexName, build);
    }

    @ApiOperation(value = "文档id 更新文档")
    @GetMapping("update")
    public String update(@RequestParam("id") String id) {
        User user = new User().setUserName("李五").setUpdateTime(System.currentTimeMillis());
        return esUtil.update(indexName, id, JSON.toJSONString(user));
    }

    @ApiOperation(value = "批更新")
    @GetMapping("updateBatch")
    public BulkResponse updateBatch() {
        Map<String, String> build = new ImmutableMap.Builder<String, String>()
                .put("2", JSON.toJSONString(new User().setUserName("张四").setUpdateTime(System.currentTimeMillis())))
                .put("3", JSON.toJSONString(new User().setUserName("张五").setUpdateTime(System.currentTimeMillis())))
                .build();
        return esUtil.insertBatch(indexName, build);
    }

    @ApiOperation(value = "文档id 删除文档")
    @GetMapping("delete")
    public String delete(@RequestParam("id") String id) {
        return esUtil.delete(indexName, id);
    }

    @ApiOperation(value = "批量删除文档")
    @GetMapping("deleteBatch")
    public List<String> deleteBatch(@RequestParam("ids") List<String> ids) {
        return esUtil.deleteBatch(indexName, ids);
    }

    @ApiOperation(value = "文档id 查询文档")
    @GetMapping("searchById")
    public String searchById(@RequestParam("id") String id) {
        return esUtil.searchById(indexName, id);
    }

    @ApiOperation(value = "查询全部的条数")
    @GetMapping("findTotal")
    public Long findTotal() {
        TermQueryBuilder queryBuilder = QueryBuilders.termQuery("userName.keyword", "王五");
        return esUtil.findTotal(indexName, queryBuilder);
    }

    @ApiOperation(value = "组合QueryBuilder 进行查询")
    @GetMapping("findAll")
    public List<Map<String, Object>> findAll() {
        QueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.fuzzyQuery("userName.keyword", "李四"));
        return esUtil.findAll(indexName, queryBuilder);
    }

    @ApiOperation(value = "分页查询文档")
    @PostMapping("fromSizePage")
    public P<Map<String, Object>> fromSizePage(@RequestBody BasePageForm basePageForm) {
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("userName.keyword", "王五");
        return esUtil.fromSizePage(indexName, termQueryBuilder, basePageForm);
    }

    @ApiOperation(value = "分页查询文档")
    @PostMapping("searchAfterPage")
    public P<Map<String, Object>> searchAfterPage(@RequestBody BasePageForm basePageForm) {
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("createTime")
                .from("1660634673318").to("1660634713318");
        return esUtil.searchAfterPage(indexName, rangeQueryBuilder, basePageForm);
    }

    @ApiOperation(value = "单字段聚合查询")
    @GetMapping("sinFieldsAggregateQuery")
    public List<Object> sinFieldsAggregateQuery() {
        // 需要分组的字段，可以随意指定
        List<String> fieldList = Lists.newArrayList("age");
        TermsAggregationBuilder termsAge = AggregationBuilders.terms(fieldList.get(0)).field(fieldList.get(0))
                .subAggregation(AggregationBuilders.avg("avg").field(fieldList.get(0)))
                .subAggregation(AggregationBuilders.sum("sum").field(fieldList.get(0)))
                .subAggregation(AggregationBuilders.min("min").field(fieldList.get(0)))
                .subAggregation(AggregationBuilders.count("count").field(fieldList.get(0)))
                .subAggregation(AggregationBuilders.cardinality("cardinality").field(fieldList.get(0)));
        return esUtil.aggregateQuery(indexName, fieldList, termsAge);
    }

    @ApiOperation(value = "多字段聚合查询")
    @GetMapping("multipleFieldsAggregateQuery")
    public List<Object> multipleFieldsAggregateQuery() {
        // 需要分组的字段，可以随意指定
        List<String> fieldList = Lists.newArrayList("age", "createTime");
        TermsAggregationBuilder termsAge = AggregationBuilders.terms(fieldList.get(0)).field(fieldList.get(0));
        TermsAggregationBuilder termsCreateTime = AggregationBuilders.terms(fieldList.get(1)).field(fieldList.get(1))
                .subAggregation(AggregationBuilders.avg("avg").field(fieldList.get(0)))
                .subAggregation(AggregationBuilders.sum("sum").field(fieldList.get(0)))
                .subAggregation(AggregationBuilders.min("min").field(fieldList.get(0)))
                .subAggregation(AggregationBuilders.count("count").field(fieldList.get(0)))
                .subAggregation(AggregationBuilders.cardinality("cardinality").field(fieldList.get(0)));
        return esUtil.aggregateQuery(indexName, fieldList, termsAge.subAggregation(termsCreateTime));
    }
}
